package com.star.mentor.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.star.mentor.dto.EvaluationPageDTO;
import com.star.mentor.dto.EvaluationSaveDTO;
import com.star.mentor.dto.EvaluationUpdateDTO;
import com.star.mentor.entity.Evaluation;
import com.star.mentor.mapper.EvaluationMapper;
import com.star.mentor.service.EvaluationItemService;
import com.star.mentor.service.EvaluationLogService;
import com.star.mentor.service.EvaluationService;
import com.star.mentor.service.MentorEvaluationService;
import com.star.mentor.struct.EvaluationStruct;
import com.star.mentor.vo.EvaluationDetailVO;
import com.star.mentor.vo.EvaluationPageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 评估规则 服务实现类
 *
 * @author yangzj
 */
@Service
public class EvaluationServiceImpl extends ServiceImpl<EvaluationMapper, Evaluation> implements EvaluationService {

    @Autowired
    private EvaluationItemService evaluationItemService;
    @Autowired
    private MentorEvaluationService mentorEvaluationService;
    @Autowired
    private EvaluationLogService evaluationLogService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(EvaluationSaveDTO dto) {
        boolean exists = this.lambdaQuery().eq(Evaluation::getEnabled, true).exists();
        Evaluation evaluation = EvaluationStruct.INSTANCE.to(dto)
                .setEnabled(!exists);
        this.save(evaluation);
        // 评估项目保存
        evaluationItemService.saveBatch(dto.getItems(), evaluation.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(EvaluationUpdateDTO dto) {
        boolean enabled = this.lambdaQuery().eq(Evaluation::getId, dto.getId()).eq(Evaluation::getEnabled, true).exists();
        Assert.isFalse(enabled, "评估规则启用中不能修改");
        Evaluation evaluation = EvaluationStruct.INSTANCE.to(dto);
        this.update(evaluation, Wrappers.<Evaluation>lambdaUpdate().eq(Evaluation::getId, dto.getId())
                .set(Evaluation::getRemark, dto.getRemark()));
        // 评估项目更新
        evaluationItemService.updateBatch(dto.getItems(), evaluation.getId());
        // 记录变更日志记录
        evaluationLogService.save(dto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateEnabled(Long id, boolean enabled) {
        Evaluation old = Assert.notNull(this.getById(id), "评估规则不存在");
        if (old.getEnabled().equals(enabled)) {
            // 没有变更
            return;
        }
        if (enabled) {
            // 启用时，其他都得禁用
            this.lambdaUpdate().set(Evaluation::getEnabled, false).update();
            this.updateById(new Evaluation().setId(id).setEnabled(true));
            // 规则启用后再分配导师, 得设置还没分配导师的学员
            mentorEvaluationService.allocationNotEvaluation();
        } else {
            // 禁用
            this.updateById(new Evaluation().setId(id).setEnabled(false));
            // 删除未评估，等待下次再分配评估ID
            mentorEvaluationService.deleteNotEvaluation(id);
            // 禁用时，得结算评估过学员
            mentorEvaluationService.disableEvaluation(id);
        }
        // 日志记录一下
        evaluationLogService.saveEnabledChange(id, old.getEnabled(), enabled);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long id) {
        // 评估规则启用中不能删除
        boolean enabled = this.lambdaQuery().eq(Evaluation::getId, id).eq(Evaluation::getEnabled, true).exists();
        Assert.isFalse(enabled, "评估规则启用中不能删除");
        // 已使用过的不能删除
        boolean used = mentorEvaluationService.exists(id);
        Assert.isFalse(used, "评估规则正在使用不能删除");
        this.removeById(id);
        evaluationItemService.deleteByEvaluationId(id);
    }

    @Override
    public IPage<EvaluationPageVO> page(EvaluationPageDTO dto) {
        return baseMapper.page(dto);
    }

    @Override
    public EvaluationDetailVO getDetail(Long id) {
        return Assert.notNull(baseMapper.getDetail(id), "评估规则不存在")
                .setItems(evaluationItemService.listDetail(id));
    }

    @Override
    public Evaluation getEnabled() {
        return this.getOne(Wrappers.<Evaluation>lambdaQuery().eq(Evaluation::getEnabled, true));
    }
}
